package com.example.societiesSystem.controller;


import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.societiesSystem.common.R;
import com.example.societiesSystem.config.UserListener;
import com.example.societiesSystem.dto.ExcelStudentDTO;
import com.example.societiesSystem.dto.ExcelUserDTO;
import com.example.societiesSystem.entity.User;
import com.example.societiesSystem.service.IUserService;
import com.example.societiesSystem.utils.EncryptUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author gl
 * @since 2025-05-21
 */
@Api(tags = "用户管理")
@CrossOrigin
@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;

    @Value("${login.prefix}")
    private String prefix;

    @ApiOperation(value = "分页查询用户")
    @GetMapping("/page")
    public R pageAll(@RequestParam("pageIndex") Long pageIndex
    , @RequestParam("pageSize") Long pageSize
    , @RequestParam(value = "userName" ,required = false) String userName
    , @RequestParam(value = "name", required = false) String name)
    {
        return R.data(userService.pageAll(pageIndex,pageSize,userName,name));
    }

    @ApiOperation(value = "查询所有用户")
    @GetMapping("/getAll")
    public R getAll() {
        return R.data(userService.getBaseMapper().selectList(null));
    }

    @ApiOperation(value = "添加用户")
    @PostMapping("/add")
    public R add(@RequestBody User user) {
        String password = user.getPassWord();
        String newPassword = EncryptUtils.md5(prefix+password);
        user.setPassWord(newPassword);
        user.setCreatedAt(LocalDateTime.now());
        Boolean save = userService.save(user);
        if (save) {
            return R.ok();
        }
        return R.error();
    }

    @ApiOperation(value = "修改用户")
    @PostMapping("/upd")
    public R upd(@RequestBody User user) {
        String password = user.getPassWord();
        if (CharSequenceUtil.isNotBlank(password)){
            String newPassword = EncryptUtils.md5(prefix+password);
            user.setPassWord(newPassword);
        }
        Boolean save = userService.updateById(user);
        if (save) {
            return R.ok();
        }
        return R.error();
    }

    @ApiOperation(value = "删除用户")
    @PostMapping("/del")
    public R del(@RequestBody User user) {
        Boolean save = userService.removeById(user);
        if (save) {
            return R.ok();
        }
        return R.error();
    }






    @ApiOperation(value = "用户登录")
    @PostMapping("/login")
    public R login(@RequestBody User user) {
        String password = user.getPassWord();
        String newPassword = EncryptUtils.md5(prefix+password);
        user.setPassWord(newPassword);
        return userService.login(user);
    }

    @ApiOperation(value = "获取用户信息")
    @GetMapping("/info")
    public R info(@RequestParam("id") Long id) {
        return R.messageData("查询成功！", userService.getById(id));
    }

    @ApiOperation(value = "用户邮箱登录")
    @PostMapping("/emailLogin")
    public R emailLogin(@RequestBody Map<String, String> map) {

        return userService.emailLogin(map);
    }


    /**
     */
    @ApiOperation(value = "用户导入")
    @PostMapping("/import")
    public R excelImport(MultipartFile file) throws IOException {
        EasyExcel.read(
                file.getInputStream(),
//                "D:\\Desktop\\study\\productionPractice\\societies_system\\users.xlsx",
                ExcelUserDTO.class,
                new UserListener(userService)
        ).sheet(0).doRead();
        return R.ok();
    }

    /**
     */
    @ApiOperation(value = "用户导出")
    @GetMapping("/export")
    public void excelExport(@RequestParam("pageIndex") Long pageIndex
            , @RequestParam("pageSize") Long pageSize
            , @RequestParam(value = "userName" ,required = false) String userName
            , @RequestParam(value = "name", required = false) String name
            , HttpServletResponse response) throws IOException {

        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("用户信息导出", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");


            IPage<User> userIPage = userService.pageAll(pageIndex, pageSize, userName, name);
            List<User> records = userIPage.getRecords();
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), ExcelUserDTO.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(records);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }


}
